package com.lcx.security.service.impl;


import com.lcx.security.FFmpegCommandManager.FFmpegManager;
import com.lcx.security.config.StreamConfig;
import com.lcx.security.dao.TaskDaoImpl;
import com.lcx.security.entity.TaskEntity;
import com.lcx.security.entity.OutHandler;
import com.lcx.security.myenum.StreamEnum;
import com.lcx.security.service.OutHandlerMethod;
import com.lcx.security.service.TaskHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * 任务处理实现
 */
public class TaskHandlerImpl implements TaskHandler {
	protected static Logger logger = LoggerFactory.getLogger(TaskHandlerImpl.class);

	private Runtime runtime = null;

	private OutHandlerMethod ohm=null;
	
	public TaskHandlerImpl(OutHandlerMethod ohm) {
		this.ohm = ohm;
	}

	public void setOhm(OutHandlerMethod ohm) {
		this.ohm = ohm;
	}

	@Override
	public TaskEntity process(String id, String command) {
		Process process = null;
		OutHandler outHandler = null;
		OutHandler outHandler1 = null;
		TaskEntity tasker = null;
		try {
			if (runtime == null) {
				runtime = Runtime.getRuntime();
			}
			logger.info("执行命令："+command);
			
			String[] cmds = {"/bin/sh","-c",command};//linux
			process = Runtime.getRuntime().exec(cmds);//linux
			
//			process = runtime.exec(command);// 执行本地命令获取任务主进程(window)
			outHandler = new OutHandler(process.getErrorStream(), id,this.ohm);
			outHandler.start();
			outHandler1 = new OutHandler(process.getInputStream(), id, this.ohm);
			outHandler1.start();
			tasker = new TaskEntity(id, process, outHandler,outHandler1);
		} catch (IOException e) {
			logger.error("执行命令失败！正在停止进程和输出线程...");
			stop(outHandler);
			stop(outHandler1);
			stop(process);
			// 出现异常说明开启失败，返回null
			return null;
		}
		return tasker;
	}

	@Override
	public boolean stop(String id,Process process) {
		if (process != null) {
			process.destroy();
			return true;
		}
		return false;
	}
	@Override
	public boolean stop(Process process) {
		return stop(null,process);
	}

	@SuppressWarnings("deprecation")
	@Override
	public boolean stop(String id,Thread outHandler) {
		if (outHandler != null ) {
			outHandler.stop();
			outHandler.destroy();
			return true;
		}
		return false;
	}
	@Override
	public boolean stop(Thread outHandler) {
		return stop((String) null,outHandler);
	}

	@Override
	public boolean stop(TaskEntity taskEntity) {
		boolean ret;
		ret=stop(taskEntity.getId(),taskEntity.getThread());
		ret=ret || stop(taskEntity.getId(),taskEntity.getThread1());
		ret=ret && stop(taskEntity.getId(),taskEntity.getProcess());
		if (taskEntity.getId() != null && ret){
			TaskEntity taskEntity1 = TaskDaoImpl.query(taskEntity.getId());
			if ( taskEntity1 != null ){
				TaskDaoImpl.delete(taskEntity.getId());
			}
		}

		Process p = null;
		try {
			if (StreamEnum.RTSP_TO_RTMP.getName().equals(taskEntity.getId())){
				String[] cmds = {"/bin/sh","-c"," ps -ef|grep stimeout|awk '{print $2}'|xargs kill -9"};//linux
				logger.info(cmds[2]);
				p = Runtime.getRuntime().exec(cmds);//linux
			}
			if (StreamEnum.RTMP_TO_HLS.getName().equals(taskEntity.getId())){
				String[] cmds = {"/bin/sh","-c"," ps -ef|grep "+ StreamConfig.HLS_URL +"|awk '{print $2}'|xargs kill -9"};//linux
				logger.info(cmds[2]);
				p = Runtime.getRuntime().exec(cmds);//linux
			}
			if (StreamEnum.HLS_TO_MP4.getName().equals(taskEntity.getId())){
				String[] cmds = {"/bin/sh","-c"," ps -ef|grep "+ StreamConfig.HIVE_URL +"|awk '{print $2}'|xargs kill -9"};//linux
				logger.info(cmds[2]);
				p = Runtime.getRuntime().exec(cmds);//linux
			}
			assert p != null;
			p.waitFor(5, TimeUnit.SECONDS);
			logger.info("关闭"+taskEntity.getId()+"成功");
		}catch (IOException | InterruptedException e){
			e.printStackTrace();
		}finally {
			if (p != null){
				p.destroy();
			}
		}


		return ret;
	}

}
